#!/usr/bin/env python
# -*- encoding: utf-8 -*-

import socket

from collections import defaultdict
from flask import render_template, request, json, abort
from .app import app
from datetime import timedelta, date


@app.route('/error/reset/<taskid>')
def error_reset(taskid):
    rpc = app.config['scheduler_rpc']
    rpc.reset_error_task(*taskid.split(':', 1))
    return '', 200


@app.route('/error/ignore/<taskid>')
def error_ignore(taskid):
    rpc = app.config['scheduler_rpc']
    rpc.ignore_error_task(*taskid.split(':', 1))
    return '', 200


@app.route('/error/ignore_date/<date>')
def error_ignore_date(date):
    errordb = app.config['errordb']
    errordb.delete(date.split(':')[0], date.split(':')[1])
    return '', 200


@app.route('/errors/count')
def errors_count():
    rpc = app.config['scheduler_rpc_del']()
    errors_task = rpc.get_error_count(app.config['errordb'].TASK_ERROR)
    errors_db = rpc.get_error_count(app.config['errordb'].DB_ERROR)
    errors_vacancy = app.config['errordb'].count_by_date(app.config['errordb'].VACANCY_ERROR, (date.today() - timedelta(days=1)).strftime('%Y-%m-%d'))
    return json.dumps([errors_task, errors_db, errors_vacancy]), 200, {'Content-Type': 'application/json'}


@app.route('/errors/<int:error_type>')
def errors_show(error_type):

    if app.config['errordb'].error_type_to_string(error_type) == 'UNKNOWN':
        abort(404)
    if app.config['errordb'].error_type_to_string(error_type) != 'VACANCY_ERROR':
        rpc = app.config['scheduler_rpc']
        limit = int(request.args.get('limit', 1000))

        try:
            pmg = rpc.get_projects_map_groups()
            error_tasks = rpc.get_error_tasks(error_type, limit)
        except socket.error as e:
            app.logger.warning('connect to scheduler rpc error: %r', e)
            return 'connect to scheduler error', 502

        # error_groups_map_projects
        egmp = defaultdict(set)
        for task in error_tasks:
            egmp[pmg[task['project']]].add(task['project'])
        for g, p in egmp.items():
            egmp[g] = list(p)

        task_group = defaultdict(list)
        for task in reversed(sorted(error_tasks, key=lambda x: x['updatetime'])):
            task_group[task['project']].append(task)

        return render_template(
            "errors.html",
            error_type=error_type,
            task_group=task_group,
            gmp=json.dumps(egmp),
            error_type_to_string=app.config['errordb'].error_type_to_string
        )
    if app.config['errordb'].error_type_to_string(error_type) == 'VACANCY_ERROR':
        rpc = app.config['scheduler_rpc']
        offset = int(request.args.get('offset', 0))
        limit = int(request.args.get('limit', 1000))

        try:
            error_vacancys = list(app.config['errordb'].select(error_type, offset=offset, limit=limit))
        except Exception as e:
            app.logger.warning('failed to select error_type, %s, %r', error_type, e)
            return 'failed to select error_type', 400

        # error_groups_map_projects
        egmp = defaultdict(set)
        task_group = defaultdict(list)
        for error_vacancy in error_vacancys:
            egmp[error_vacancy['group']].add(error_vacancy['project'])
            task_group[error_vacancy['project']].append(error_vacancy['date'])
        for g, p in egmp.items():
            egmp[g] = list(p)

        return render_template(
            "error_vacancy.html",
            error_type=error_type,
            task_group=task_group,
            gmp=json.dumps(egmp),
            error_type_to_string=app.config['errordb'].error_type_to_string
        )


@app.route('/error/<taskid>')
def error_show(taskid):
    if ':' not in taskid:
        abort(400)
    rpc = app.config['scheduler_rpc']
    try:
        error_task = rpc.get_error_task(*taskid.split(':', 1))[0]
    except socket.error as e:
        app.logger.warning('connect to scheduler rpc error: %r', e)
        return 'connect to scheduler error', 502

    for key in ('group', 'mark', 'project_updatetime', 'project_md5sum'):
        if key in error_task:
            del error_task[key]
    return render_template("error.html", task=error_task, json=json,
                           result=error_task['result'] if 'result' in error_task else [],
                           error_type_to_string=app.config['errordb'].error_type_to_string)
